#pragma once
#include <Rz/IObject.h>
#include <Rz/Memory.h>
#include <Rz/Collections/List.h>
#include <Rz/Graphics/Math/Vector2.h>
#include <Rz/Graphics/Render/ViewerState.h>
#include <Rz/Graphics/Render/IRenderDevice.h>
#include <Rz/Graphics/Render/IViewerHandler.h>
#include <Rz/Graphics/Render/ViewerEvents.h>


namespace Rz { namespace Graphics { namespace Render {

class IViewer :
	virtual public IObject
{
	public:
		RZ_RTTI_INTERFACE(Rz::Graphics::Render, IViewer);
		RZ_RTTI_IMPLEMENTS(IObject);
		RZ_RTTI_END;

		virtual bool Init(const ViewerState& state) = 0;
		virtual void End() = 0;
		virtual void Run() = 0;

		RZ_INLINE virtual void AddViewport(Viewport* viewport) { _viewports.Add(viewport); }
		RZ_INLINE virtual void RemoveViewport(Viewport* viewport) { _viewports.Remove(viewport); }
		RZ_INLINE virtual Viewport* GetViewportAt(size_t index) { return _viewports[index]; }

		RZ_INLINE virtual const IViewerHandler* GetViewerHandler() const { return _viewerHandler; }
		RZ_INLINE virtual IViewerHandler* GetViewerHandler() { return _viewerHandler; }
		RZ_INLINE virtual void SetViewerHandler(IViewerHandler* viewerHandler) { _viewerHandler = viewerHandler; }

		RZ_INLINE virtual const IRenderDevice* GetRenderDevice() const { return _renderDevice; }
		RZ_INLINE virtual IRenderDevice* GetRenderDevice() { return _renderDevice; }
		RZ_INLINE virtual void SetRenderDevice(IRenderDevice* device) { _renderDevice = device; }

		RZ_INLINE virtual const ViewerState& GetViewerState() const { return _viewerState; }
		RZ_INLINE virtual void SetViewerState(const ViewerState& state) { _viewerState = state; }

// 		RZ_INLINE virtual const Vector2& GetViewerSize() const { return _viewerState.ViewerSize; }
// 		RZ_INLINE virtual void SetViewerSize(const Vector2& size) { _viewerState.ViewerSize = size; }

		RZ_INLINE virtual const bool IsFullscreen() const { return _viewerState.Fullscreen; }
		RZ_INLINE virtual void SetFullscreen(bool fullscreen) { _viewerState.Fullscreen = fullscreen ; }

		RZ_INLINE const Events::EventInfo* GetEventInfo() const { return &_eventInfo; }

		RZ_INLINE virtual bool IsActive() const { return _isActive; }

	protected:
		IViewer()
			: _isActive(true)	// REVIEW
		{
			Memory::Set(&_eventInfo, 0, sizeof(_eventInfo));
		}

		RZ_INLINE virtual void SetActiveStatus(bool active) { _isActive = active; }
		RZ_INLINE Events::EventInfo* GetEventInfo() { return &_eventInfo; }

	private:
		Collections::List<Ptr<Viewport>> _viewports;

		Events::EventInfo _eventInfo;
		Ptr<IRenderDevice> _renderDevice;
		Ptr<IViewerHandler> _viewerHandler;
		ViewerState _viewerState;
		bool _isActive;
};

} } }
